using System;
using System.Collections;
using System.Collections.Generic;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
using Server.Regions;
using Server.Multis;


namespace Server.Items
{
	public class CommVendorDeed : Item
	{
		private int m_Serial;

		[Constructable]
		public CommVendorDeed( int serial ) : base( 0x14F0 )
		{
			Weight = 1.0;
			Hue = 60;
			Name = "a commissioned contract";
			LootType = LootType.Blessed;
			m_Serial = serial;
		}

		[Constructable]
		public CommVendorDeed() : this( int.MinValue )
		{
		}

		public CommVendorDeed( Serial serial ) : base( serial )
		{
		}


		public override void OnDoubleClick( Mobile from )
		{
			if ( !IsChildOf( from.Backpack ) )
			{
				from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
			}
			else if ( m_Serial > 0 )
			{
				from.Target = new InternalTarget( this, m_Serial );
				from.SendMessage( "Target a vendor tile to place your vendor" );
			}
			else
			{
				// it is now a normal player vendor contract
				BaseHouse house = BaseHouse.FindHouseAt( from );

				if ( house == null )
				{
					from.SendLocalizedMessage( 503240 ); // Vendors can only be placed in houses.	
				}
				else if ( !BaseHouse.NewVendorSystem && !house.IsFriend( from ) )
				{
					from.SendLocalizedMessage( 503242 ); // You must ask the owner of this building to name you a friend of the household in order to place a vendor here.
				}
				else if ( BaseHouse.NewVendorSystem && !house.IsOwner( from ) )
				{
					from.SendLocalizedMessage( 1062423 ); // Only the house owner can directly place vendors.  Please ask the house owner to offer you a vendor contract so that you may place a vendor in this house.
				}
				else if ( !house.Public || !house.CanPlaceNewVendor() ) 
				{
					from.SendLocalizedMessage( 503241 ); // You cannot place this vendor or barkeep.  Make sure the house is public and has sufficient storage available.
				}
				else
				{
					bool vendor, contract;
					BaseHouse.IsThereVendor( from.Location, from.Map, out vendor, out contract );

					if ( vendor )
					{
						from.SendLocalizedMessage( 1062677 ); // You cannot place a vendor or barkeep at this location.
					}
					else if ( contract )
					{
						from.SendLocalizedMessage( 1062678 ); // You cannot place a vendor or barkeep on top of a rental contract!
					}
					else
					{
						Mobile v = CreateHomeVendor( from, house );

						v.Direction = from.Direction & Direction.Mask;
						v.MoveToWorld( from.Location, from.Map );

						v.SayTo( from, 503246 ); // Ah! it feels good to be working again.

						this.Delete();
					}
				}
			}
		}

		public Mobile CreateHomeVendor( Mobile from, BaseHouse house )
		{
			if ( CommissionedVendor.AllowPlaceHome )
			{
				CommissionedVendor cv = new CommissionedVendor( from, house );
				return cv;
			}
			else
				return new PlayerVendor( from, house );
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( (int)0 ); //version

			writer.Write( (int) m_Serial );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();

			m_Serial = reader.ReadInt();
		}


		private class InternalTarget : Target
		{
			private CommVendorDeed m_Deed;
			private VendorManager m_Manager;
			private int m_Serial;

			public InternalTarget( CommVendorDeed deed, int serial ) : base( 6, false, TargetFlags.None )
			{
				m_Deed = deed;
				m_Serial = serial;
				m_Manager = null;
			}

			protected override void OnTarget( Mobile from, object targeted )
			{
				if ( m_Deed == null || m_Deed.Deleted || !( m_Serial > 0 ) )
					return;

				if ( targeted == null || !( targeted is CommVendorTile ) )
				{
					from.SendMessage( "That is not the vendor tile required." );
					return;
				}

				CommVendorTile tile = targeted as CommVendorTile;
				Region reg = Region.Find( tile.Location, tile.Map );
				List<Region> regs = new List<Region>();

				while ( reg != null )
				{
					if ( reg is VendorRegion )
						regs.Add( reg );

					reg = reg.Parent;
				}

				if ( regs == null || !( regs.Count > 0 ) )
				{
					from.SendMessage( "The tile isn't inside the mall." );
					return;
				}

				reg = null;
				foreach ( Region region in regs )
				{
					VendorManager vm = ((VendorRegion)region).Manager;
					if ( vm != null && (int)vm.Serial == m_Serial )
					{
						m_Manager = vm;
						reg = region;
					}
				}

				if ( ( reg != null && reg is VendorRegion ) || from.AccessLevel >= AccessLevel.GameMaster )
				{
					Mobile v = new CommissionedVendor( from, null );

					if ( m_Manager != null && !m_Manager.Deleted && m_Manager.CommRate > 0 )
					{
						((CommissionedVendor)v).CommRate = m_Manager.CommRate;
						((CommissionedVendor)v).Manager = m_Manager;
					}

					v.Direction = from.Direction & Direction.Mask;

					try
					{
						v.MoveToWorld( tile.Location, tile.Map );
						m_Manager.Workers.Add( (Mobile)v );
					}
					catch
					{
					}

					v.SayTo( from, 503246 ); // Ah! it feels good to be working again.

					tile.Delete();
					m_Deed.Delete();
				}
				else
				{
					from.SendMessage( "Your deed doesn't seem to work on the tile. {0}", reg.Name.ToString() );
					return;
				}
			}
		}
	}


	public class StayHomeDeed : CommVendorDeed
	{
		[Constructable]
		public StayHomeDeed() : base( int.MinValue )
		{
			Name = "a stay home deed";
			Hue = 10;
			LootType = LootType.Blessed;
		}

		public StayHomeDeed( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int) 0 ); // version
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();
		}
	}
}
